package com.forest.service.impl;

import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.StrUtil;
import com.forest.constants.EncryptionAlgorithm;
import com.forest.dto.AuthDTO;
import com.forest.dto.AuthEncryptionDTO;
import com.forest.dto.ValidateSignatureDTO;
import com.forest.entity.SysAppInfo;
import com.forest.service.SignatureService;
import com.forest.service.SysAppInfoService;
import com.forest.util.EncryptionKeyUtil;
import com.forest.util.EnvironmentHolder;
import com.forest.util.SignParamUtil;
import com.forest.util.SignUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

/**
 * @author Administrator
 */
@Slf4j
@Service
public class SignatureServiceImpl implements SignatureService {

    @Resource
    private SysAppInfoService sysAppInfoService;

    @Override
    public boolean verify(AuthDTO dto) {
        Assert.notBlank(dto.getAppKey(), "appKey不能为空");
        Assert.notBlank(dto.getSignature(), "signature不能为空");
        Assert.notBlank(dto.getTimestamp(), "timestamp不能为空");
        SysAppInfo appInfo = sysAppInfoService.getByAppKey(dto.getAppKey());
        Assert.notNull(appInfo, "应用信息不存在");
        return verify(dto, appInfo);
    }

    @Override
    public boolean verify(AuthDTO dto, SysAppInfo appInfo) {
        int type = EncryptionAlgorithm.SM4.getAlgorithm().equals(StrUtil.isBlank(appInfo.getEncryptionAlgorithm()) ? EnvironmentHolder.getEncryptionAlgorithm() : appInfo.getEncryptionAlgorithm()) ? 1 : 2;
        return SignUtil.getInstance().verify(ValidateSignatureDTO.builder()
                .appKey(appInfo.getAppKey())
                .appSecret(EncryptionKeyUtil.getAppSecretKey(type,appInfo.getAppSecret()))
                .appIv(EncryptionKeyUtil.getAppSecretKey(type,appInfo.getAppIv()))
                .timestamp(dto.getTimestamp())
                .signature(dto.getSignature())
                .extra(dto.getExtra())
                .expireSeconds(appInfo.getExpireSeconds())
                .signatureAlgorithm(appInfo.getSignatureAlgorithm())
                .build());
    }

    @Override
    public boolean verify(AuthEncryptionDTO dto) {
        Assert.notBlank(dto.getAppKey(), "appKey不能为空");
        SysAppInfo appInfo = sysAppInfoService.getByAppKey(dto.getAppKey());
        Assert.notNull(appInfo, "应用信息不存在");
        return verify(dto, appInfo);
    }


    @Override
    public boolean verify(AuthEncryptionDTO dto, SysAppInfo appInfo) {
        int type = EncryptionAlgorithm.SM4.getAlgorithm().equals(StrUtil.isBlank(appInfo.getEncryptionAlgorithm()) ? EnvironmentHolder.getEncryptionAlgorithm() : appInfo.getEncryptionAlgorithm()) ? 1 : 2;
        String secretKey = sysAppInfoService.decryptKey(appInfo);
        AuthDTO authDTO = SignParamUtil.unAuthEncryptionParam(dto, StrUtil.isBlank(appInfo.getEncryptionAlgorithm()) ? EnvironmentHolder.getEncryptionAlgorithm() : appInfo.getEncryptionAlgorithm(), secretKey);
        Assert.notBlank(authDTO.getSignature(), "signature不能为空");
        Assert.notBlank(authDTO.getTimestamp(), "timestamp不能为空");
        return SignUtil.getInstance().verify(ValidateSignatureDTO.builder()
                .appKey(appInfo.getAppKey())
                .appSecret(EncryptionKeyUtil.getAppSecretKey(type,appInfo.getAppSecret()))
                .appIv(EncryptionKeyUtil.getAppSecretKey(type,appInfo.getAppIv()))
                .timestamp(authDTO.getTimestamp())
                .signature(authDTO.getSignature())
                .extra(authDTO.getExtra())
                .expireSeconds(appInfo.getExpireSeconds())
                .signatureAlgorithm(appInfo.getSignatureAlgorithm())
                .build());
    }
}
